﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Compiler.Modules
{
    internal class StringParser
    {
        public static string GetKeyword(string line)
        {
            return line.Trim().Split(new[] { ' ', '(', '=' })[0].Trim();
        }

        public static string GetWord(string line, int word)
        {
            string currentLine = line.Trim();

            if (currentLine.Length == 0 || currentLine.IndexOf(' ') == -1)
            {
                return currentLine;
            }

            string[] words = currentLine.Split(' ');

            if (word > (words.Length - 1))
            {
                return "";
            }

            return words[word].Trim();
        }

        public static string[] GetWords(string line)
        {
            string currentLine = line.Trim();

            if (currentLine.Length == 0 || currentLine.IndexOf(' ') == -1)
            {
                return new[] { currentLine };
            }

            return currentLine.Split(' ');
        }

        public static int GetWordCount(string line)
        {
            string currentLine = line.Trim();

            if (currentLine.Length == 0)
            {
                return 0;
            }

            string[] words = currentLine.Split(' ');

            return words.Length;
        }

        public static string[] GetParameters(string line, bool excludeKeyword = false)
        {
            string currentLine = line.Trim();
            var parameters = new List<string>();

            if (currentLine.Length == 0 || GetWordCount(currentLine) <= 1)
            {
                return new string[0];
            }

            currentLine = (excludeKeyword ? GetLineExcludingKeyword(currentLine) : currentLine);

            string currentParam = "";
            bool inQuotes = false;
            int bracketCount = 0;

            foreach (char letter in currentLine)
            {
                if (letter == '"')
                {
                    currentParam += '"';
                    inQuotes = !inQuotes;
                    continue;
                }

                if (letter == '(')
                {
                    if (inQuotes)
                    {
                        currentParam += '(';
                        continue;
                    }
                    currentParam += '(';
                    bracketCount++;
                    continue;
                }

                if (letter == ')')
                {
                    if (inQuotes)
                    {
                        currentParam += ')';
                        continue;
                    }
                    currentParam += ')';
                    bracketCount--;
                    continue;
                }

                if (letter == ',')
                {
                    if (inQuotes)
                    {
                        currentParam += ',';
                        continue;
                    }
                    if (bracketCount == 0)
                    {
                        parameters.Add(currentParam.Trim());
                        currentParam = "";
                        continue;
                    }
                }

                currentParam += letter;
            }
            if (!string.IsNullOrEmpty(currentParam))
            {
                parameters.Add(currentParam.Trim());
            }

            return parameters.ToArray<string>();
        }

        public static string GetLineExcludingKeyword(string line)
        {
            string currentLine = line.Trim();

            if (currentLine.Length == 0) return "";

            string keyword = GetKeyword(currentLine);

            if (currentLine.Length <= keyword.Length)
            {
                return "";
            }

            return currentLine.Substring((keyword.Length)).Trim();
        }

        public static int CountSymbolOccurances(string line, char symbol)
        {
            //This counts the number of times a symbol occurs on a line - not including those in a string
            int count = 0;
            bool inQuotes = false;

            foreach (char letter in line)
            {
                if (letter == '"')
                {
                    inQuotes = !inQuotes;
                    continue;
                }

                if (letter == symbol && !inQuotes)
                {
                    count++;
                }
            }

            return count;
        }

        public static string GetBracketContents(string line)
        {
            string contents = "";
            int bracketCount = 0;
            bool inBrackets = false;
            bool inQuotes = false;

            foreach (char letter in line)
            {
                if (letter == '"' && inBrackets)
                {
                    contents += letter;
                    inQuotes = !inQuotes;
                    continue;
                }
                if (inQuotes)
                {
                    contents += letter;
                    continue;
                }

                if (letter == '(' && !inBrackets)
                {
                    inBrackets = true;
                    continue;
                }

                if (letter == '(' && inBrackets)
                {
                    bracketCount++;
                    contents += '(';
                    continue;
                }

                if (letter == ')' && inBrackets)
                {
                    if (bracketCount <= 0)
                    {
                        return contents;
                    }

                    bracketCount--;
                    contents += ')';
                    continue;
                }

                if (inBrackets) contents += letter;
            }
            return contents;
        }

        public static string GetQuoteContents(string phrase)
        {
            return phrase.Substring(phrase.IndexOf("\"", StringComparison.Ordinal), phrase.LastIndexOf("\"", StringComparison.Ordinal) - phrase.IndexOf("\"", StringComparison.Ordinal));
        }
    }
}